//package com.manage.common.util;
//
//import org.I0Itec.zkclient.IZkDataListener;
//import org.I0Itec.zkclient.ZkClient;
//import org.I0Itec.zkclient.exception.ZkNodeExistsException;
//
//import java.util.Collections;
//import java.util.List;
//import java.util.concurrent.CountDownLatch;
//import java.util.concurrent.TimeUnit;
//import java.util.concurrent.locks.Condition;
//import java.util.concurrent.locks.Lock;
//
///**
// * zookeeper分布式锁，已经解决了惊群效应
// * @author duaiyu
// * @version V1.0
// * @date 2022/3/2
// * 来源：自研
// */
//public class ZKDistributedLock implements Lock {
//    /**
//     * 利用临时顺序节点来解决zookeeper分布式锁的惊群效应
//     * 获取锁：创建自己的临时节点，然后判断自己是否是最小号
//     * 如果是，则获得锁，不是，则注册前一节点的watcher，阻塞等待
//     * 释放锁：删除自己创建的临时顺序节点
//     */
//    private String lockPath;
//    private ZkClient client;
//    private String currentPath;
//    private String beforePath;
//    //记录是否持有锁的线程
//    private Thread owner;
//
//    public ZKDistributedLock(String lockPath){
//        super();
//        this.lockPath = lockPath;
//        client = new ZkClient("59.110.173.112:2181");
//        client.setZkSerializer(new MyZkSerializer());
//        if(!this.client.exists(this.lockPath)){
//            try {
//                this.client.createPersistent(this.lockPath);
//            }catch (ZkNodeExistsException e){
//
//            }
//        }
//    }
//
//    @Override
//    public void lock() {
//        while (!tryLock()){
//            //阻塞等待
//            waitForLock();
//        }
//    }
//
//    private void waitForLock() {
//        CountDownLatch cd1 = new CountDownLatch(1);
//
//        //注册watcher
//        IZkDataListener listener = new IZkDataListener() {
//            @Override
//            public void handleDataChange(String s, Object o) throws Exception {
//
//            }
//
//            @Override
//            public void handleDataDeleted(String s) throws Exception {
//                System.out.println("--- 节点被删除 ---");
//                //唤醒阻塞线程
//                cd1.countDown();
//            }
//        };
//        client.subscribeDataChanges(this.beforePath, listener);
//
//        //怎么让自己阻塞
//        if (this.client.exists(this.beforePath)){
//            try {
//                cd1.await();
//            }catch (InterruptedException e){
//                e.printStackTrace();
//            }
//        }
//        //醒来后取消watcher
//        client.unsubscribeDataChanges(this.beforePath, listener);
//    }
//
//    @Override
//    public void lockInterruptibly() throws InterruptedException {
//
//    }
//
//    @Override
//    public boolean tryLock() {
//        //判断是否已经有号
//        if(this.currentPath == null){
//            //创建一个临时顺序节点
//            currentPath = this.client.createEphemeralSequential(this.lockPath+"/", "id");
//        }
//        //获得所有的子
//        List<String> children = this.client.getChildren(this.lockPath);
//
//        //排序list
//        Collections.sort(children);
//        //判断当前节点是否是最小的
//        if(currentPath.equals(this.lockPath+"/"+children.get(0))){
//            owner = Thread.currentThread();
//            return true;
//        }else{
//            //取到前一个
//            //得到子节点的索引号
//            int curIndex = children.indexOf(currentPath.substring(this.lockPath.length()+1));
//            beforePath = this.lockPath+"/"+children.get(curIndex - 1);
//        }
//        return false;
//    }
//
//    @Override
//    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
//        return false;
//    }
//
//    @Override
//    public void unlock() {
//        //必须持有锁的线程才可以执行unlock逻辑
//        if(Thread.currentThread() != owner){
//            return;
//        }
//        //释放锁的时候把owner置空
//        owner = null;
//        //删除节点
//        this.client.delete(this.currentPath);
//
//    }
//
//    @Override
//    public Condition newCondition() {
//        return null;
//    }
//
//}
